#include "needle_valve_menu.h"
#include "menu_config.h"
#include "../Application/channel_output.h"

/* 针阀开度调节步长宏定义 */
#define NEEDLE_VALVE_SHORT_STEP  1   /* 短按步长 0.1% */
#define NEEDLE_VALVE_LONG_STEP   10  /* 长按步长 1.0% */

/* 针阀开度范围定义 */
#define NEEDLE_VALVE_MIN_PERCENT  0    /* 最小开度 0% */
#define NEEDLE_VALVE_MAX_PERCENT  1000 /* 最大开度 100.0% (以0.1%为单位) */

/* 电流输出范围定义 */
#define CURRENT_MIN_UA  4000   /* 最小电流 4mA = 4000μA */
#define CURRENT_MAX_UA  20000  /* 最大电流 20mA = 20000μA */

/* 针阀控制信息结构体 */
typedef struct {
    uint16_t openingPercent;     /* 针阀开度，单位：0.1% (0-1000对应0.0%-100.0%) */
    uint16_t currentOutput;      /* 对应的电流输出，单位：μA (4000-20000μA) */
} NeedleValveInfo_t;

/* 添加全屏刷新标志位 */
static bool needFullRefresh = true;
/* 显示刷新标志，决定是否需要重绘菜单界面 */
static bool sg_needRefresh = true;
/* 当前针阀控制信息 */
static NeedleValveInfo_t sg_needleValve;

/* 定义空的菜单项 */
static cotMenuList_t sg_NeedleValveMenuTable[] =
{
    COT_MENU_ITEM_BIND(TEXT_NEEDLE_VALVE_OPENING, NULL, NULL, NULL, NULL, "Needle Valve Control"),
};

/* 将针阀开度百分比转换为电流输出 */
static uint16_t ConvertPercentToCurrent(uint16_t percent)
{
    /* percent范围：0-1000 (对应0.0%-100.0%) */
    /* 电流范围：4000-20000μA (4-20mA) */
    /* 转换公式：current = 4000 + (percent * 16000) / 1000 */
    uint32_t current = CURRENT_MIN_UA + ((uint32_t)percent * (CURRENT_MAX_UA - CURRENT_MIN_UA)) / NEEDLE_VALVE_MAX_PERCENT;
    return (uint16_t)current;
}

/* 将电流输出转换为针阀开度百分比 */
static uint16_t ConvertCurrentToPercent(uint16_t current)
{
    /* 电流范围：4000-20000μA (4-20mA) */
    /* percent范围：0-1000 (对应0.0%-100.0%) */
    /* 转换公式：percent = (current - 4000) * 1000 / 16000 */
    if (current < CURRENT_MIN_UA) current = CURRENT_MIN_UA;
    if (current > CURRENT_MAX_UA) current = CURRENT_MAX_UA;
    
    uint32_t percent = ((uint32_t)(current - CURRENT_MIN_UA) * NEEDLE_VALVE_MAX_PERCENT) / (CURRENT_MAX_UA - CURRENT_MIN_UA);
    return (uint16_t)percent;
}

/* 初始化针阀控制信息 */
static void InitNeedleValveInfo(void)
{
    /* 获取通道5的当前电流输出值 */
    uint16_t currentOutput = ChannelOutput_GetCurrent(5);
    
    /* 将电流值转换为针阀开度百分比 */
    sg_needleValve.openingPercent = ConvertCurrentToPercent(currentOutput);
    sg_needleValve.currentOutput = currentOutput;
}

/* 应用当前针阀开度到硬件 */
static void ApplyNeedleValveOutput(void)
{
    /* 将针阀开度转换为电流输出 */
    sg_needleValve.currentOutput = ConvertPercentToCurrent(sg_needleValve.openingPercent);
    
    /* 设置通道5的电流输出 */
    ChannelOutput_SetCurrent(5, sg_needleValve.currentOutput);
}

/* 显示函数 */
static void ShowNeedleValveMenu(cotMenuShow_t *ptShowInfo)
{
    /* 如果不需要刷新显示，直接返回 */
    if (!sg_needRefresh)
    {
        return;
    }

    /* 只有在首次显示或标记需要全刷时才清屏并绘制所有内容 */
    if (needFullRefresh)
    {
        /* 清屏 */
        LCD_Clear();

        /* 显示标题 */
        const char *pszSelectDesc = get_text((TextId_e)ptShowInfo->uMenuDesc.textId);
        uint16_t titleX = CALC_TITLE_CENTER_X(pszSelectDesc, LCD_W);
        LCD_ShowString(titleX, 0, (uint8_t *)pszSelectDesc, g_point_color, g_back_color, MENU_FONT_SIZE, 0);

        /* 画分隔线 */
        LCD_DrawLine(0, MENU_FONT_SIZE, LCD_W - 1, MENU_FONT_SIZE, g_point_color);

        /* 显示标签 */
        LCD_ShowString(10, 40, (uint8_t *)"Opening:", g_point_color, g_back_color, 24, 0);
        LCD_ShowString(10, 80, (uint8_t *)"Current:", g_point_color, g_back_color, 24, 0);
        LCD_ShowString(10, 120, (uint8_t *)"Output:", g_point_color, g_back_color, 24, 0);

        needFullRefresh = false;
    }

    /* 显示针阀开度百分比 */
    char percentStr[32];
    sprintf(percentStr, "%d.%d%%    ", sg_needleValve.openingPercent / 10, sg_needleValve.openingPercent % 10);
    LCD_ShowString(120, 40, (uint8_t *)percentStr, g_point_color, g_back_color, 24, 0);
    
    /* 显示设定电流值 */
    char currentStr[32];
    sprintf(currentStr, "%d.%03dmA  ", sg_needleValve.currentOutput / 1000, sg_needleValve.currentOutput % 1000);
    LCD_ShowString(120, 80, (uint8_t *)currentStr, g_point_color, g_back_color, 24, 0);
    
    /* 显示实际输出值 */
    float actualValue = ChannelOutput_GetActualOutput(5);
    char actualStr[32];
    sprintf(actualStr, "%.3fmA  ", actualValue);
    LCD_ShowString(120, 120, (uint8_t *)actualStr, g_point_color, g_back_color, 24, 0);
    
    sg_needRefresh = false;
}

/* 按键回调函数 - 上键(KEY0) */
static void OnKey0FunCB(cotKey_t key)
{
    /* 处理按键短按和长按 */
    if (!cotKey_IsLongPress(key))
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            /* 预留：首次按下按键时的处理 */
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            /* 增加针阀开度 */
            uint16_t newPercent = sg_needleValve.openingPercent + NEEDLE_VALVE_SHORT_STEP;
            if (newPercent <= NEEDLE_VALVE_MAX_PERCENT)
            {
                sg_needleValve.openingPercent = newPercent;
                ApplyNeedleValveOutput();
                sg_needRefresh = true; /* 只标记局部刷新 */
            }
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            /* 长按增加针阀开度 */
            uint16_t newPercent = sg_needleValve.openingPercent + NEEDLE_VALVE_LONG_STEP;
            if (newPercent <= NEEDLE_VALVE_MAX_PERCENT)
            {
                sg_needleValve.openingPercent = newPercent;
                ApplyNeedleValveOutput();
                sg_needRefresh = true; /* 只标记局部刷新 */
            }
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            /* 预留：长按上键松手时的处理 */
        }
    }
}

/* 按键回调函数 - 下键(KEY1) */
static void OnKey1FunCB(cotKey_t key)
{
    /* 处理按键短按和长按 */
    if (!cotKey_IsLongPress(key))
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            /* 预留：首次按下按键时的处理 */
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            /* 减少针阀开度 */
            if (sg_needleValve.openingPercent >= NEEDLE_VALVE_SHORT_STEP)
            {
                sg_needleValve.openingPercent -= NEEDLE_VALVE_SHORT_STEP;
                ApplyNeedleValveOutput();
                sg_needRefresh = true; /* 只标记局部刷新 */
            }
            else if (sg_needleValve.openingPercent > NEEDLE_VALVE_MIN_PERCENT)
            {
                /* 处理小于最小步长的特殊情况，直接设为最小值 */
                sg_needleValve.openingPercent = NEEDLE_VALVE_MIN_PERCENT;
                ApplyNeedleValveOutput();
                sg_needRefresh = true;
            }
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            /* 长按减少针阀开度 */
            if (sg_needleValve.openingPercent >= NEEDLE_VALVE_LONG_STEP)
            {
                sg_needleValve.openingPercent -= NEEDLE_VALVE_LONG_STEP;
                ApplyNeedleValveOutput();
                sg_needRefresh = true; /* 只标记局部刷新 */
            }
            else if (sg_needleValve.openingPercent > NEEDLE_VALVE_MIN_PERCENT)
            {
                /* 如果不足长按步长，但大于最小值，则设为最小值 */
                sg_needleValve.openingPercent = NEEDLE_VALVE_MIN_PERCENT;
                ApplyNeedleValveOutput();
                sg_needRefresh = true;
            }
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            /* 预留：长按下键松手时的处理 */
        }
    }
}

/* 按键回调函数 - 确认键(KEY2) */
static void OnKey2FunCB(cotKey_t key)
{
    /* 处理按键短按和长按 */
    if (!cotKey_IsLongPress(key))
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            /* 预留：首次按下按键时的处理 */
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            /* 参数已在ApplyNeedleValveOutput中自动保存 */
            /* 返回上级菜单 */
            cotMenu_Exit(false);
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            /* 参数已在ApplyNeedleValveOutput中自动保存 */
            /* 保存参数并返回主菜单 */
            while (cotMenu_Exit(true) == 0)
            {
            }
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            /* 预留：长按确认键松手时的处理 */
        }
    }
}

/* 进入回调函数 */
void OnNeedleValveMenuEnter(const cotMenuItemInfo_t *ptItemShowInfo)
{
    /* 初始化针阀控制信息 */
    InitNeedleValveInfo();
    
    /* 绑定菜单表和显示函数 */
    cotMenu_Bind(sg_NeedleValveMenuTable, COT_GET_MENU_NUM(sg_NeedleValveMenuTable), ShowNeedleValveMenu);
    
    /* 应用初始值 */
    ApplyNeedleValveOutput();
}

/* 加载回调函数 */
void LoadNeedleValveMenu(const cotMenuItemInfo_t *ptItemShowInfo)
{
    /* 注册按键回调 */
    cotKey_Listen(KEY0, OnKey0FunCB);
    cotKey_Listen(KEY1, OnKey1FunCB);
    cotKey_Listen(KEY2, OnKey2FunCB);

    /* 配置按键模式 */
    cotKey_ConfigLongPressMode(KEY0, 800, 100); /* 上键长按0.8秒触发,每0.1秒重复一次 */
    cotKey_ConfigLongPressMode(KEY1, 800, 100); /* 下键长按0.8秒触发,每0.1秒重复一次 */
    cotKey_ConfigLongPressMode(KEY2, 3000, 0);  /* SET键长按3秒触发,不重复 */
    
    /* 标记需要刷新且全屏刷新 */
    sg_needRefresh = true;
    needFullRefresh = true;
}

/* 任务回调函数 */
void NeedleValveMenuTask(const cotMenuItemInfo_t *ptItemShowInfo)
{
    /* 预留：可在此添加菜单定时刷新、动画等功能 */
}
